/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simplemetrosystem.view.canvas.MouseHandlers;

import java.awt.Cursor;
import java.awt.event.MouseEvent;
import simplemetrosystem.control.EditCommandManager;
import simplemetrosystem.model.Element.Interface.Selectable;
import simplemetrosystem.model.Element.Interface.CanvasElement;
import simplemetrosystem.model.Element.MetroStation;
import simplemetrosystem.model.Element.MetroString;
import simplemetrosystem.view.MetroFrame;
import simplemetrosystem.view.canvas.CanvasModel;

/**
 *
 * @author Eric Qian
 */
public class SelectedMouseHandler extends BasicMouseHandler {

    public SelectedMouseHandler(MetroFrame frame) {
        super(frame);
        this.frame = frame;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        super.mouseClicked(e);

        CanvasModel model = CanvasModel.getInstance();
        int x = MouseTrans.X(e.getX());
        int y = MouseTrans.Y(e.getY());
        if (model.isSelectedEmpty(x, y)) {
            model.cancelSelect();
            frame.getMetroTabbedPane().getAllLineCanvas().setSelectingMouseHandler();
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        super.mousePressed(e);
        CanvasModel model = CanvasModel.getInstance();
        int x = MouseTrans.X(e.getX());
        int y = MouseTrans.Y(e.getY());
        if (!model.isSelectedEmpty(x, y)) {
            pressed = true;
            x1 = e.getX();
            y1 = e.getY();
            elements = new Selectable[model.getSelectedElementSize()];
            for (int i = 0; i < elements.length; i++) {
                elements[i] = model.getSelectedElementAt(i);
            }
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        super.mouseDragged(e);
        if (pressed) {
            int x = e.getX();
            int y = e.getY();
            for (int i = 0; i < elements.length; i++) {
                elements[i].setShadow(pressed, x - x1, y - y1);
            }
            frame.getMetroTabbedPane().getAllLineCanvas().repaint();
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        super.mouseReleased(e);
        if (pressed) {
            CanvasModel model = CanvasModel.getInstance();
            EditCommandManager editCommandManager = EditCommandManager.getInstance();
            int tx1 = MouseTrans.X(x1);
            int ty1 = MouseTrans.Y(y1);
            int x2 = MouseTrans.X(e.getX());
            int y2 = MouseTrans.Y(e.getY());
            MetroStation tStation;
            MetroString tString;
            pressed = false;

            boolean check = true;

            for (int i = 0; i < elements.length; i++) {
                if (elements[i] instanceof MetroStation) {
                    tStation = (MetroStation) elements[i];
                    if (tStation.getLogX() + x2 - tx1 < 0 ||
                            tStation.getLogX() + tStation.getWidth() +
                            x2 - tx1 >= model.getMatrixWidth() ||
                            tStation.getLogY() + y2 - ty1 < 0 ||
                            tStation.getLogY() + tStation.getHeight() +
                            y2 - ty1 >= model.getMatrixHeight()) {
                        check = false;
                    } else if (!model.isStationAvailable(tStation.getLogX() + x2 - tx1,
                            tStation.getLogY() + y2 - ty1)) {
                        check = false;
                    }
                } else if (elements[i] instanceof MetroString) {
                    tString = (MetroString) elements[i];
                    if (tString.getLogX() + x2 - tx1 < 0 ||
                            tString.getLogX() + tString.getWidth() +
                            x2 - tx1 >= model.getMatrixWidth() ||
                            tString.getLogY() + y2 - ty1 < 0 ||
                            tString.getLogY() + tString.getHeight() +
                            y2 - ty1 >= model.getMatrixHeight()) {
                        check = false;
                    } else if (!model.isStationAvailable(tString.getLogX() + x2 - tx1,
                            tString.getLogY() + y2 - ty1)) {
                        check = false;
                    }
                }
                elements[i].setShadow(pressed, 0, 0);
            }

            if (check) {
                for (int i = 0; i < elements.length; i++) {
                    if (elements[i] instanceof MetroStation) {
                        tStation = (MetroStation) elements[i];
                        editCommandManager.EditStation(tStation, tStation.getName(),
                                tStation.getChineseName(), tStation.getLogX() + x2 - tx1,
                                tStation.getLogY() + y2 - ty1, tStation.getNatX(),
                                tStation.getNatY());
                    } else if (elements[i] instanceof MetroString) {
                        tString = (MetroString) elements[i];
                        editCommandManager.EditString(tString, tString.getName(),
                                tString.getLogX() + x2 - tx1, tString.getLogY() + y2 - ty1);
                    }

                }
            }
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        super.mouseEntered(e);
        frame.setCursor(defaultCursor);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        super.mouseExited(e);
        frame.setCursor(defaultCursor);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        super.mouseMoved(e);
        CanvasModel model = CanvasModel.getInstance();
        int x = MouseTrans.X(e.getX());
        int y = MouseTrans.Y(e.getY());
        if (!model.isSelectedEmpty(x, y)) {
            frame.setCursor(moveCursor);
        } else {
            frame.setCursor(defaultCursor);
        }
    }
    private MetroFrame frame;
    private boolean pressed;
    private Selectable[] elements;
    private int x1;
    private int y1;
    private static Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
}
